package com.example.redissondemo.utils;

import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author Liunh
 */
@Slf4j
public class DateUtil {

    public static final String DATE_FORMAT_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_NUMBER = "yyyyMMddHHmmss";
    public static final String DATE_FORMAT_NUMBER_MILLISECOND = "yyyyMMddHHmmssSSS";
    public static final String DATE_FORMAT_HOUR_PATTERN = "yyyy-MM-dd HH";
    public static final String DATE_FORMAT_HOUR_PATTERN1 = "yyyyMMdd HH";
    public static final String DATE_FORMAT_DAY_PATTERN = "yyyy-MM-dd";
    public static final String DATE_FORMAT_DAY_PATTERN1 = "yyyyMMdd";
    public static final String DATE_FORMAT_MONTH_PATTERN = "yyyy-MM";
    public static final String DATE_FORMAT_MONTH_PATTERN1 = "yyyyMM";
    public static final String DATE_FORMAT_YEAR_PATTERN = "yyyy";
    public static final String YEAR_MONTH_DAY_EN_SECOND = "yyyy/MM/dd HH:mm:ss";
    public static final String DAY_MONTH_YEAR_EN = "dd/MM/yyyy";
    public static final String YEAR_MONTH_DAY_EN = "yyyy/MM/dd";
    public static final String YEAR_MONTH_DAY_CN_SECOND = "yyyy年MM月dd日 HH时mm分ss秒";
    public static final String YEAR_MONTH_DAY_CN = "yyyy年MM月dd日";
    public static final String START_DAY_SUFFIX = "-01-01";
    public static final String START_MONTH_DAY_SUFFIX = "-01";
    public static final String END_DAY_SUFFIX = "-12-31";
    public static final String START_TIME_SUFFIX = " 00:00:00";
    public static final String END_TIME_SUFFIX = " 23:59:59";

    /**
     * 采用 ThreadLocal 避免 SimpleDateFormat 非线程安全的问题
     * <p>
     * Key —— 时间格式
     * Value —— 解析特定时间格式的 SimpleDateFormat
     */
    private static ThreadLocal<Map<String, SimpleDateFormat>> sThreadLocal = new ThreadLocal<>();


    /**
     * 获取解析特定时间格式的 SimpleDateFormat
     *
     * @param pattern 时间格式
     */
    public static SimpleDateFormat getDateFormat(String pattern) {
        if (StringUtils.isBlank(pattern)) {
            pattern = DATE_FORMAT_DEFAULT;
        }
        Map<String, SimpleDateFormat> strDateFormatMap = sThreadLocal.get();
        if (strDateFormatMap == null) {
            strDateFormatMap = new HashMap<>();
        }
        SimpleDateFormat simpleDateFormat = strDateFormatMap.get(pattern);
        if (simpleDateFormat == null) {
            simpleDateFormat = new SimpleDateFormat(pattern, Locale.getDefault());
            strDateFormatMap.put(pattern, simpleDateFormat);
            sThreadLocal.set(strDateFormatMap);
        }

        return simpleDateFormat;
    }


    public static Date toDate(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static String format(LocalDateTime dateTime, String format) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(format));
    }

    public static LocalDateTime parse(String dateTimeStr, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (dateTimeStr == null) {
            return null;
        }
        final DateTimeFormatter sf = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(dateTimeStr, sf);
    }

    public static String format(LocalDateTime dateTime) {
        return format(dateTime, DATE_FORMAT_DEFAULT);
    }

    public static LocalDateTime parse(String dateTimeStr) {
        return parse(dateTimeStr, DATE_FORMAT_DEFAULT);
    }

    // #############################################################################

    /**
     * 时间格式转换为字符串格式
     *
     * @param date   时间
     * @param format 格式 如("yyyy-MM-dd hh:mm:ss")
     * @return String
     */
    public static String date2Str(Date date, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (date == null) {
            return null;
        }
        final String getDateFormat = getDateFormat(format).format(date);
        sThreadLocal.remove();
        return getDateFormat;
    }

    public static String date2Str(Date date) {
        if (date == null) {
            return null;
        }
        final String getDateFormat = getDateFormat(DATE_FORMAT_DEFAULT).format(date);
        sThreadLocal.remove();
        return getDateFormat;
    }

    public static String currentStrDate() {
        final String getDateFormat = getDateFormat(DATE_FORMAT_DEFAULT).format(new Date());
        sThreadLocal.remove();
        return getDateFormat;
    }

    public static String strDate(String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        final String getDateFormat = getDateFormat(format).format(new Date());
        sThreadLocal.remove();
        return getDateFormat;
    }

    /**
     * 字符串格式转换为时间格式
     *
     * @param dateStr 字符串
     * @return Date
     */
    public static Date str2Date(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        try {
            Date date = null;
            if (dateStr.length() == 4) {
                date = getDateFormat(DATE_FORMAT_YEAR_PATTERN).parse(dateStr);
            } else if (dateStr.length() == 10 && dateStr.contains("-")) {
                date = getDateFormat(DATE_FORMAT_DAY_PATTERN).parse(dateStr);
            } else if (dateStr.length() == 13 && NumberUtil.getInstance().isNumber(dateStr)) {
                date = getDateFormat(DATE_FORMAT_NUMBER).parse(dateStr);
            } else if (dateStr.length() > 10 && dateStr.contains("/") && dateStr.contains(":")) {
                date = getDateFormat(YEAR_MONTH_DAY_EN_SECOND).parse(dateStr);
            } else if (dateStr.length() < 11 && dateStr.indexOf("/") == 2) {
                date = getDateFormat(DAY_MONTH_YEAR_EN).parse(dateStr);
            } else if (dateStr.length() < 11 && dateStr.indexOf("/") == 4) {
                date = getDateFormat(YEAR_MONTH_DAY_EN).parse(dateStr);
            } else if (dateStr.length() > 10 && dateStr.contains("-") && dateStr.contains(":")) {
                date = getDateFormat(DATE_FORMAT_DEFAULT).parse(dateStr);
            }
            sThreadLocal.remove();
            return date;
        } catch (ParseException pe) {
            log.error(pe.getMessage());
            return null;
        }
    }

    /**
     * 字符串格式转换为时间格式
     *
     * @param dateStr 字符串
     * @param format  格式 如("yyyy-MM-dd HH:mm:ss")
     * @return Date
     */
    public static Date str2Date(String dateStr, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        try {
            final Date date = getDateFormat(format).parse(dateStr);
            sThreadLocal.remove();
            return date;
        } catch (ParseException pe) {
            log.error(pe.getMessage());
            return null;
        }
    }

    /**
     * @param timestamp：时间
     */
    public static Date parse(long timestamp) {
        return new Date(timestamp);
    }

    /**
     * 获取当前日期
     *
     * @param pattern 格式如:yyyy-MM-dd
     * @return
     */
    public static Date getCurrentDate(String pattern) {
        final Date date = str2Date(getDateFormat(pattern).format(new Date()), pattern);
        sThreadLocal.remove();
        return date;
    }

    public static Date getCurrentDate() {
        final Date date = str2Date(getDateFormat(DATE_FORMAT_DEFAULT).format(new Date()), DATE_FORMAT_DEFAULT);
        sThreadLocal.remove();
        return date;
    }

    /**
     * get cuurent Date return java.util.Date type
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * get current Date return java.sql.Date type
     *
     * @return
     */
    public static java.sql.Date getNowSqlDate() {
        return new java.sql.Date(System.currentTimeMillis());
    }

    /**
     * get the current timestamp return java.sql.Timestamp
     *
     * @return
     */
    public static Timestamp getNowTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static long date2Timestamp(Date date) {
        return new Timestamp(date.getTime()).getTime();
    }

    public static Date timestamp2Date(Timestamp timestamp) {
        return new Date(timestamp.getTime());
    }

    public static Date timestamp2Date(Long timestamp) {
        return new Date(timestamp);
    }

    /**
     * time1>time2 返回正数
     *
     * @param time1
     * @param time2
     * @return
     */
    public static long getOffsetBetweenTimes(String time1, String time2) {
        final Date date1 = str2Date(time1, DATE_FORMAT_DEFAULT);
        final Date date2 = str2Date(time2, DATE_FORMAT_DEFAULT);
        if (date1 != null && date2 != null) {
            return date1.getTime() - date2.getTime();
        }
        return 0;
    }


    /**
     * 返回时间差
     *
     * @param start
     * @param end
     * @param timeUnit 天d, 时h, 分m, 秒s
     * @return 根据timeUnit返回
     */
    public static long getOffsetBetweenDate(Date start, Date end, char timeUnit) {
        long result = 0L;
        if (start != null && end != null) {
            //定义上机时间
            final long startT = start.getTime();
            //定义下机时间
            final long endT = end.getTime();
            //共计秒数
            final long ss = (startT - endT) / (1000);
            //共计分钟数
            final int mm = (int) ss / 60;
            //共计小时数
            final int hh = (int) ss / 3600;
            //共计天数
            final int dd = hh / 24;
            if ('d' == timeUnit) {
                result = dd;
            } else if ('h' == timeUnit) {
                result = hh;
            } else if ('m' == timeUnit) {
                result = mm;
            } else if ('s' == timeUnit) {
                result = ss;
            }
        }
        return result;
    }

    /**
     * 对指定日期滚动指定天数,负数时,则往前滚,正数时,则往后滚
     *
     * @param date  Date
     * @param years int
     * @return String
     */
    public static Date rollYears(Date date, int years) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, years);
        return calendar.getTime();
    }

    /**
     * 对指定日期滚动指定天数,负数时,则往前滚,正数时,则往后滚
     *
     * @param date   Date
     * @param months int
     * @return String
     */
    public static Date rollMonths(Date date, int months) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 对指定日期滚动指定天数,负数时,则往前滚,正数时,则往后滚
     *
     * @param date Date
     * @param days int
     * @return String
     */
    public static Date rollDays(Date date, int days) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        return calendar.getTime();
    }

    /**
     * 对指定日期滚动指定分钟,负数时,则往前滚,正数时,则往后滚
     *
     * @param date    Date
     * @param minutes int
     * @return String
     */
    public static Date rollMinutes(Date date, int minutes) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 对指定日期滚动指定分钟,负数时,则往前滚,正数时,则往后滚
     *
     * @param date    Date
     * @param seconds int
     * @return String
     */
    public static Date rollSeconds(Date date, int seconds) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }

    /**
     * 对指定日期滚动指定分钟,负数时,则往前滚,正数时,则往后滚
     *
     * @param date    Date
     * @param seconds int
     * @return String
     */
    public static String rollSeconds(Date date, int seconds, String format) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return date2Str(calendar.getTime(), format);
    }

    /**
     * 返回  2013-01-16T06:24:26.829Z 时间
     *
     * @param date
     * @return
     * @throws Exception
     */
    public static XMLGregorianCalendar getXmlDatetime(Date date) throws Exception {
        if (null == date) {
            date = new Date();
        }
        GregorianCalendar nowGregorianCalendar = new GregorianCalendar();
        final XMLGregorianCalendar xmlDatetime = DatatypeFactory.newInstance().newXMLGregorianCalendar(nowGregorianCalendar);
        // XMLGregorianCalendar ->GregorianCalendar
        nowGregorianCalendar = xmlDatetime.toGregorianCalendar();
        nowGregorianCalendar.setTime(date);
        return xmlDatetime;
    }

    public static boolean checkDateBetweenBoth(Date checkDate, Date date1, Date date2) {
        boolean temp = false;
        if (checkDate == null || date1 == null || date2 == null) {
            return temp;
        }
        if (checkDate.equals(date1) || checkDate.equals(date2)) {
            temp = true;
        }
        if (checkDate.after(date1) && checkDate.before(date2)) {
            temp = true;
        }
        return temp;
    }

    public static String getFormatDatetime() {
        final GregorianCalendar gCalendar = new GregorianCalendar();
        String strDateTime;
        try {
            strDateTime = getDateFormat(DATE_FORMAT_DEFAULT).format(gCalendar.getTime());
            sThreadLocal.remove();
        } catch (Exception ex) {
            log.error(ex.getMessage());
            return null;
        }
        return strDateTime;
    }


    /**
     * 判断给定的日期是一年中的第几天
     *
     * @param dateTimeStr
     * @return
     */
    public static int dayOfYear(String dateTimeStr) {
        if (StringUtils.isBlank(dateTimeStr)) {
            return 0;
        }
        final Date dateTime = str2Date(dateTimeStr, DATE_FORMAT_DEFAULT);
        return dayOfYear(dateTime);
    }


    /**
     * 判断给定的日期是一年中的第几天
     *
     * @param dateTime
     * @return
     */
    public static int dayOfYear(Date dateTime) {
        int year, month, date;
        if (null == dateTime) {
            return 0;
        }
        final String dateTimeStr = date2Str(dateTime, null);
        final LocalDateTime localDateTime = parse(dateTimeStr);
        year = localDateTime.getYear();
        month = localDateTime.getMonthValue();
        date = localDateTime.getDayOfMonth();
        return dayOfYear(year, month, date);
    }


    /**
     * 判断给定的日期是一年中的第几天
     *
     * @param year
     * @param month
     * @param date
     * @return
     */
    public static int dayOfYear(int year, int month, int date) {
        final int[] days = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int day = 0;
        //判断是不是闰年，然后设置二月的天数
        if ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))) {
            days[2] = 29;
        } else {
            days[2] = 28;
        }
        for (int i = 1; i < month; i++) {
            day += days[i];
        }
        day += date;
        return day;
    }


    public static Calendar date2Calendar(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    public static int getYearFromDate(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    public static int getYear(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    public static int getYearOfMonth(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    public static String getYearFirstDayTime(Date date) {
        return getYear(date) + START_DAY_SUFFIX + START_TIME_SUFFIX;
    }

    public static String getCurrentYearFirstDayTime() {
        return getYear(new Date()) + START_DAY_SUFFIX + START_TIME_SUFFIX;
    }

    public static int getMonthOfDay(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    public static String getMonthFirstDayTime(Date date, String format) {
        return date2Str(date, format) + START_MONTH_DAY_SUFFIX + START_TIME_SUFFIX;
    }

    public static String getCurrentMonthFirstDayTime() {
        return getCurrentMonthFirstDay() + START_TIME_SUFFIX;
    }

    public static String getCurrentMonthFirstDay() {
        final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_DAY_PATTERN);
        final Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);
        return sdf.format(lastDate.getTime());
    }

    public static String getLastDayOfMonth(Date date) {
        final Calendar calendar = date2Calendar(date);
        return getLastDayOfMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1);
    }

    public static String getLastDayOfMonth(int year, int month) {
        final Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        final int lastDay = cal.getMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, lastDay - 1);
        final String getDateFormat = getDateFormat(DATE_FORMAT_DAY_PATTERN).format(cal.getTime());
        sThreadLocal.remove();
        return getDateFormat;
    }

    public static List<String> getYearOfQuarter(String startTime, String endTime) {
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            return getYearOfQuarter(str2Date(startTime, DATE_FORMAT_MONTH_PATTERN), str2Date(endTime, DATE_FORMAT_MONTH_PATTERN));
        }
        return Collections.emptyList();
    }

    public static List<String> getYearOfQuarter(Date startTime, Date endTime) {
        final List<String> dates = new ArrayList<>();
        if (startTime != null && endTime != null) {
            final List<String> tempList = getTimeListBetweenDate(startTime, endTime, Calendar.MONTH);
            final Set<String> dateSet = new HashSet<>();
            if (!CollectionUtils.isEmpty(tempList)) {
                for (String date : tempList) {
                    dateSet.add(getYearOfQuarter(str2Date(date, DATE_FORMAT_MONTH_PATTERN)));
                }
                dates.addAll(dateSet);
            }
            if (!CollectionUtils.isEmpty(dates)) {
                dates.sort(String::compareTo);
            }
        }
        return dates;
    }

    public static String getYearOfQuarter(String date) {
        return getYearOfQuarter(str2Date(date, DATE_FORMAT_DAY_PATTERN));
    }

    public static String getYearOfQuarter(Date date) {
        final int year = getYearFromDate(date);
        final int month = getYearOfMonth(date);
        String result = year + "-1季度";
        if (month <= Constant.NUMBER_THREE) {
            result = year + "-1季度";
        } else if (month > Constant.NUMBER_THREE && month <= Constant.NUMBER_SIX) {
            result = year + "-2季度";
        } else if (month > Constant.NUMBER_SIX && month <= Constant.NUMBER_NINE) {
            result = year + "-3季度";
        } else if (month > Constant.NUMBER_NINE) {
            result = year + "-4季度";
        }
        return result;
    }

    public static String getQuarterFirstDayTime(Date date) {
        final int year = getYearFromDate(date);
        final int month = getYearOfMonth(date);
        return getQuarterFirstDayTimeStr(year, month);
    }

    private static String getQuarterFirstDayTimeStr(int year, int month) {
        String result = year + START_DAY_SUFFIX + START_TIME_SUFFIX;
        if (month <= Constant.NUMBER_THREE) {
            result = year + START_DAY_SUFFIX + START_TIME_SUFFIX;
        }
        if (month > Constant.NUMBER_THREE && month <= Constant.NUMBER_SIX) {
            result = year + "-04-01" + START_TIME_SUFFIX;
        }
        if (month > Constant.NUMBER_SIX && month <= Constant.NUMBER_NINE) {
            result = year + "-07-01" + START_TIME_SUFFIX;
        }
        if (month > Constant.NUMBER_NINE) {
            result = year + "-10-01" + START_TIME_SUFFIX;
        }
        return result;
    }

    public static String getCurrentQuarterFirstDayTime() {
        final int year = getYearFromDate(new Date());
        final int month = getYearOfMonth(new Date());
        return getQuarterFirstDayTimeStr(year, month);
    }

    /**
     * 获取两个日期之间的所有年/月/日集合(年月日)
     * 查询时间类型：1 年，2 年-月，3 年-月-日，4 年季
     *
     * @param startTime 年-月-日
     * @param endTime   年-月-日
     * @param timeUnit  1 年，2 年-月，3 年-月-日，4 年季
     * @return
     * @throws Exception
     */
    public static List<String> getTimeListBetweenDate(Date startTime, Date endTime, Integer timeUnit) {
        final List<String> dates = new ArrayList<>();
        try {
            timeUnit = timeUnit == null ? 1 : timeUnit;
            if (timeUnit < Constant.NUMBER_ONE || timeUnit > Constant.NUMBER_FOUR) {
                timeUnit = 1;
            }
            if (startTime != null && endTime != null) {
                SimpleDateFormat sdf;
                if (timeUnit == Constant.NUMBER_FOUR) {
                    return getYearOfQuarter(startTime, endTime);
                } else if (timeUnit == Constant.NUMBER_THREE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_DAY_PATTERN);
                } else if (timeUnit == Constant.NUMBER_TWO) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_MONTH_PATTERN);
                } else if (timeUnit == Constant.NUMBER_ONE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_YEAR_PATTERN);
                } else if (timeUnit == Constant.NUMBER_FIVE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_HOUR_PATTERN);
                } else {
                    sdf = new SimpleDateFormat(DATE_FORMAT_DAY_PATTERN);
                }
                dates.add(sdf.format(startTime));
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(startTime);
                while (endTime.after(calendar.getTime())) {
                    if (timeUnit == Constant.NUMBER_THREE) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    } else if (timeUnit == Constant.NUMBER_TWO) {
                        calendar.add(Calendar.MONTH, 1);
                    } else if (timeUnit == Constant.NUMBER_ONE) {
                        calendar.add(Calendar.YEAR, 1);
                    } else if (timeUnit == Constant.NUMBER_FIVE) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    } else {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    dates.add(sdf.format(calendar.getTime()));
                }
            }
        } catch (Exception e) {
            log.error("获取两个日期之间的所有年/月/日集合(年月日)异常！", e);
        }
        return dates;
    }

    /**
     * 获取两个日期之间的所有年/月/日集合(年月日)
     * 查询时间类型：1 年，2 年-月，3 年-月-日，4 年季
     *
     * @param startTime 年-月-日
     * @param endTime   年-月-日
     * @param timeUnit  1 年，2 年-月，3 年-月-日，4 年季
     * @return
     * @throws Exception
     */
    public static List<String> getTimeListBetweenDate(String startTime, String endTime, Integer timeUnit) {
        List<String> dates = new ArrayList<>();
        try {
            timeUnit = timeUnit == null ? 1 : timeUnit;
            if (timeUnit < Constant.NUMBER_ONE || timeUnit > Constant.NUMBER_FOUR) {
                timeUnit = 1;
            }
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                SimpleDateFormat sdf;
                if (timeUnit == Constant.NUMBER_FOUR) {
                    return getYearOfQuarter(startTime, endTime);
                } else if (timeUnit == Constant.NUMBER_THREE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_DAY_PATTERN);
                } else if (timeUnit == Constant.NUMBER_TWO) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_MONTH_PATTERN);
                } else if (timeUnit == Constant.NUMBER_ONE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_YEAR_PATTERN);
                } else if (timeUnit == Constant.NUMBER_FIVE) {
                    sdf = new SimpleDateFormat(DATE_FORMAT_HOUR_PATTERN);
                } else {
                    sdf = new SimpleDateFormat(DATE_FORMAT_DAY_PATTERN);
                }
                final Date dBegin = sdf.parse(startTime);
                final Date dEnd = sdf.parse(endTime);
                dates = getTimeListBetweenDate(dBegin, dEnd, timeUnit);
            }
        } catch (Exception e) {
            log.error("获取两个日期之间的所有年/月/日集合(年月日)异常！", e);
        }
        return dates;
    }

    /**
     * 获取24小时
     *
     * @return
     */
    public static List<Integer> get24Hour() {
        final List<Integer> dates = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            dates.add(i);
        }
        return dates;
    }

    public static List<String> get24Hour1() {
        final List<String> dates = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            dates.add(String.valueOf(i));
        }
        return dates;
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     *
     * @param date
     * @return
     */
    public static String getWeek1(Date date) {
        final Calendar c = Calendar.getInstance();
        c.setTime(date);
        return new SimpleDateFormat("EEEE").format(c.getTime());
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     *
     * @param date
     * @return
     */
    public static int getWeek2(Date date) {
        final Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获得当前日期与本周日相差的天数
     *
     * @return
     */
    public static int getMondayPlus() {
        final Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        //int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1;//因为按中国礼拜一作为第一天所以这里减1
        final int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }

    public static String getCurrentWeekSundayTime() {
        return getCurrentWeekSunday() + START_TIME_SUFFIX;
    }

    /**
     * 获得本周星期日的日期
     *
     * @return
     */
    public static String getCurrentWeekSunday() {
        int mondayPlus = getMondayPlus();
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    /**
     * 获得本周一的日期
     *
     * @return
     */
    public static String getCurrentWeekMonday() {
        int mondayPlus = getMondayPlus() + 1;
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    /**
     * 获得上周星期日的日期
     *
     * @return
     */
    public static String getPreWeekSunday() {
        int mondayPlus = getMondayPlus();
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 7);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    /**
     * 获得上周星期一的日期
     *
     * @return
     */
    public static String getPreWeekMonday() {
        int mondayPlus = getMondayPlus();
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 6);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    /**
     * 获得下周星期日的日期
     *
     * @return
     */
    public static String getNextSunday() {
        int mondayPlus = getMondayPlus();
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    /**
     * 获得下周星期一的日期
     *
     * @return
     */
    public static String getNextMonday() {
        int mondayPlus = getMondayPlus();
        final GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 8);
        final Date monday = currentDate.getTime();
        return date2Str(monday, DATE_FORMAT_DAY_PATTERN);
    }

    public static String getDayStartTime(Date date, String format) {
        return date2Str(date, format) + START_TIME_SUFFIX;
    }

    public static String getCurrentDayStartTime() {
        return date2Str(new Date(), DATE_FORMAT_DAY_PATTERN) + START_TIME_SUFFIX;
    }

    public static String getCurrentDayEndTime() {
        return date2Str(new Date(), DATE_FORMAT_DAY_PATTERN) + END_TIME_SUFFIX;
    }

    public static Date getOnlyDate(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Date(calendar.getTimeInMillis());
    }

    public static Date getOnlyMonth(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, 1);
        return new Date(calendar.getTimeInMillis());
    }

    public static Date getOnlyYear(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, 1);
        calendar.set(Calendar.DATE, 1);
        return new Date(calendar.getTimeInMillis());
    }

    /**
     * 根据身份证号获取时间
     */
    public static Date getDateByIdentity(String identity) {
        if (StringUtils.isNotBlank(identity)) {
            return null;
        }
        String birthdayStr;
        if (identity.length() == 18) {
            birthdayStr = identity.substring(6, 14);
        } else {
            birthdayStr = "19" + identity.substring(6, 12);
        }
        return str2Date(birthdayStr, "yyyyMMdd");
    }

    /**
     * 获得年度第几周
     */
    public static Integer getWeekOfYear(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    public static Date getWeekOfMonday(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return calendar.getTime();
    }

    public static Integer getDayOfWeek(Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (weekDay < 0) {
            weekDay = 0;
        }
        return weekDay;
    }

    public static String getYearMonthDay(Date date) {
        if (date == null) {
            return "";
        }
        final String year = String.valueOf(DateUtil.getYear(date));
        String month = String.valueOf(DateUtil.getYearOfMonth(date));
        month = month.length() == 1 ? "0" + month : month;
        String day = String.valueOf(DateUtil.getMonthOfDay(date));
        day = day.length() == 1 ? "0" + day : day;
        return String.format("%s%s%s", year, month, day).substring(2);
    }
}
